package com.yanqu.road.server.gameplayer.module.activity.recallplayer;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.oldplayerreturn.OldPlayerReturnUserData;
import com.yanqu.road.entity.activity.recallplayer.config.RecallPlayerConfig;
import com.yanqu.road.entity.activity.recallplayer.config.RecallPlayerDrawConfig;
import com.yanqu.road.entity.activity.recallplayer.config.RecallPlayerSingleSimpleRewardConfig;
import com.yanqu.road.entity.activity.recallplayer.config.RecallPlayerTypeConfig;
import com.yanqu.road.entity.activity.recallplayer.data.*;
import com.yanqu.road.entity.config.system.PropertyWeightItem;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.LogRecallPlayerDraw;
import com.yanqu.road.entity.log.LogRecallPlayerFinishBindUserTaskReward;
import com.yanqu.road.entity.log.LogRecallUser;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.task.args.RecallPlayerActivitySumArgs;
import com.yanqu.road.logic.bussiness.activity.RecallPlayerBusiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.RandomWeightConfigHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.pb.RecallPlayerPb;
import com.yanqu.road.pb.activity.RecallPlayerProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.oldplayerreturn.OldPlayerReturnModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.AttributeModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.oldplayerreturn.OldPlayerReturnMgr;
import com.yanqu.road.server.manger.activity.recallplayer.RecallPlayerMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class RecallPlayerModule extends GeneralModule {

    private UserRecallBeBindData beBindData;

    private UserRecallSelfData userRecallSelfData;

    private Map<Long, List<RecallPlayerBindingTaskData>> bindingUserTaskDataMap = new ConcurrentHashMap<>();
    //绑定玩家的信息 上线载入,下线删除
    private Map<Long, UserBaseInfo> recallUserBaseInfoMap = new ConcurrentHashMap<>();

    public RecallPlayerModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return true;
        }
        reloadActivityData(activityInfo.getActivityId());
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if (beBindData != null) {
            if (beBindData.isInsertOption()) {
                RecallPlayerBusiness.addUserRecallBeBindData(beBindData);
            } else if (beBindData.isUpdateOption()) {
                RecallPlayerBusiness.updateUserRecallBeBindData(beBindData);
            }
        }
        if (userRecallSelfData != null) {
            if (userRecallSelfData.isInsertOption()) {
                RecallPlayerBusiness.addUserRecallSelfData(userRecallSelfData);
            } else if (userRecallSelfData.isUpdateOption()) {
                RecallPlayerBusiness.updateUserRecallSelfData(userRecallSelfData);
            }
        }
        for (List<RecallPlayerBindingTaskData> bindingTaskDataList : bindingUserTaskDataMap.values()) {
            for (RecallPlayerBindingTaskData recallPlayerBindingTaskData : bindingTaskDataList) {
                if (recallPlayerBindingTaskData.isInsertOption()) {
                    RecallPlayerBusiness.addRecallPlayerBindingTaskData(recallPlayerBindingTaskData);
                } else if (recallPlayerBindingTaskData.isUpdateOption()) {
                    RecallPlayerBusiness.updateRecallPlayerBindingTaskData(recallPlayerBindingTaskData);
                }
            }
        }

        return true;
    }

    @Override
    public void loginSendMsg() {

    }

    @Override
    public void afterLogin() {
        syncConfig();
        syncUserData();
    }

    private boolean checkServerOpenDayEnough() {
        RecallPlayerConfig config = RecallPlayerMgr.getConfig();
        if (config == null){
            return false;
        }
        if (ServerListMgr.getServerOpenDay(GameServer.getInstance().getServerId()) >= config.getNeedOpenServerDay()) {
            return true;
        }
        return false;
    }

    private boolean checkUserTitleEnough(){
        RecallPlayerConfig config = RecallPlayerMgr.getConfig();
        if (config == null){
            return false;
        }
        return  player.getTitleId() >=  config.getNeedTitle();
    }

    public void syncConfig() {
        syncLevelConfig();
        syncDrawConfig();
        syncPosterQRCode();
    }

    public void syncPosterQRCode(){
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        RecallPlayerProto.RecallPlayerPosterQRCodeSync.Builder builder = RecallPlayerProto.RecallPlayerPosterQRCodeSync.newBuilder();
        builder.setIsDisplay(ChannelConfig.RECALL_PLAY_DISPLAY_QR_CODE);
        String appId = player.getAppId();
        String resultQrCode = "";
        if (StringUtils.isNullOrEmpty(appId)){
            appId = "default";
        }

        JSONObject dataObj  = JSONObject.parseObject(ChannelConfig.RECALL_PLAYER_QR_CODE);
        if (dataObj != null){           //解析出来不为空
            String dataObjString = dataObj.getString(appId);
            if (dataObjString != null){             //有这个key才赋值
                resultQrCode = dataObjString;
            }
        }

        builder.setQRCode(resultQrCode);
        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_POSTER_QR_CODE,builder);
    }

    public void syncUserData() {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        if (checkUserTitleEnough() && checkServerOpenDayEnough()){
            if (userRecallSelfData == null){
                initSystem();
            }
            Map<Integer, List<UserRecallOtherData>> userRecallAllOtherDataMap = RecallPlayerMgr.getUserRecallAllOtherData(getUserId());
            if (userRecallAllOtherDataMap != null) {
                //更新个人绑定数据
                newBindPlayerInit(userRecallAllOtherDataMap);
                //更新所有绑定人任务
                updateAllBindUserTask(userRecallAllOtherDataMap);
            }
            //检测是不是抽奖盘面更改
            checkNewDrawMap();
        }

        syncActivityData();

    }

    public void reloadActivityData(int activityId) {
        //同步同步配置
        syncConfig();
        //拿出被活跃玩家绑定信息
        beBindData = RecallPlayerBusiness.getUserRecallBeBindData(getUserId());
        if (checkServerOpenDayEnough() && checkUserTitleEnough() && SystemOpenMgr.systemOpen(player, eSystemId.RecallPlayerActivity.getValue())) {
            userRecallSelfData = RecallPlayerBusiness.getUserRecallSelfData(getUserId());
            //满足条件则生成初始数据
            if (userRecallSelfData == null) {
                initUserData(activityId);
            }
            //加载绑定玩家的任务数据
            bindingUserTaskDataMap = RecallPlayerBusiness.getBindingTaskData(player.getUserId());
            //加载绑定玩家的个人信息
            loadBindUserInfoCache();
        }

        syncUserData();
    }


    /**
     * 初始化数据
     *
     * @param activityId
     */
    private synchronized void initUserData(int activityId) {
        if (userRecallSelfData != null) {
            return;
        }
        String recallCode = RecallPlayerMgr.generateRecallCode(player.getUserId());
        UserRecallSelfData tempData = new UserRecallSelfData();
        tempData.setUserId(getUserId());
        tempData.setRecallCode(recallCode);
        tempData.setHasFirstShared(false);
        tempData.setRemainingLotteryTimes(0);
        tempData.setHasDrawTimeThisFloor(0);
        tempData.setFloor(1);
        tempData.setCellDataList(generateRewardList(1));
        tempData.setInsertOption();
        userRecallSelfData = tempData;
        //去mgr加个用于判断的
        RecallPlayerMgr.addUserRecallCode(getUserId(), recallCode);
    }

    private void syncLevelConfig() {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        List<RecallPlayerTypeConfig> recallPlayerTypeConfigList = RecallPlayerMgr.getConfig().getRecallPlayerTypeConfigList();
        RecallPlayerProto.RecallPlayerLevelConfigSync.Builder builder = RecallPlayerProto.RecallPlayerLevelConfigSync.newBuilder();
        for (RecallPlayerTypeConfig recallPlayerTypeConfig : recallPlayerTypeConfigList) {
            RecallPlayerProto.RecallPlayerLevelConfig.Builder configBuilder = RecallPlayerProto.RecallPlayerLevelConfig.newBuilder();
            configBuilder.setId(recallPlayerTypeConfig.getId());
            configBuilder.setIcon(recallPlayerTypeConfig.getIcon());
            configBuilder.setName(ServerLanguageMgr.getContent(recallPlayerTypeConfig.getName(), player.getUserInfo().getLanguage()));
            configBuilder.setScore(recallPlayerTypeConfig.getScore());
            configBuilder.setDrawNum(recallPlayerTypeConfig.getDrawNum());
            builder.addConfig(configBuilder);
        }
        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_LEVEL_CONFIG_SYNC, builder);

    }

    private void syncDrawConfig() {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        Map<Integer, RecallPlayerDrawConfig> drawConfig = RecallPlayerMgr.getConfig().getDrawConfig();
        RecallPlayerProto.RecallPlayerDrawConfigSync.Builder builder = RecallPlayerProto.RecallPlayerDrawConfigSync.newBuilder();
        for (RecallPlayerDrawConfig recallPlayerDrawConfig : drawConfig.values()) {
            RecallPlayerProto.RecallPlayerDrawConfig.Builder configBuilder = RecallPlayerProto.RecallPlayerDrawConfig.newBuilder();
            configBuilder.setFloor(recallPlayerDrawConfig.getFloor());
            configBuilder.setConsume(recallPlayerDrawConfig.getConsume());
            for (String string : recallPlayerDrawConfig.getSpecialReward()) {
                configBuilder.addSpecialReward(string);
            }
            for (RecallPlayerSingleSimpleRewardConfig simpleRewardConfig : recallPlayerDrawConfig.getSimpleRewardConfigs()) {
                RecallPlayerProto.RecallPlayerSingleSimpleRewardConfig.Builder simpleBuilder = RecallPlayerProto.RecallPlayerSingleSimpleRewardConfig.newBuilder();
                simpleBuilder.setOneTimeWeight(simpleRewardConfig.getOneTimeWeight());
                simpleBuilder.setReward(simpleRewardConfig.getReward());
                configBuilder.addSimpleConfig(simpleBuilder);
            }
            configBuilder.setSpecialRewardWeights(recallPlayerDrawConfig.getSpecialRewardWeights());
            configBuilder.setRewardsWeights(recallPlayerDrawConfig.getRewardsWeights());
            configBuilder.setShowValue(recallPlayerDrawConfig.getShowValue());
            builder.addConfig(configBuilder);
        }
        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_DRAW_CONFIG_SYNC, builder);
    }

    /**
     * 选择大奖
     */
    public int chooseBigReward(String reward) {
        if (StringUtils.isNullOrEmpty(reward)) {
            return GameErrorCode.E_RECALL_PLAYER_CHOOSEBIG_REWARD_NO_EXIST;
        }
        if (RecallPlayerMgr.getConfig() == null) {
            return GameErrorCode.E_RECALL_PLAYER_DRAW_CONFIG_ERROR;
        }
        if (userRecallSelfData == null) {
            return GameErrorCode.E_RECALL_PLAYER_NO_OPEN;
        }
        //初次选择
        if (getChosenBigReward() == null) {
            RecallPlayerFloorCellData cellData = generateBigReward(reward);
            userRecallSelfData.getCellDataList().add(cellData);
        } else {
            if (getChosenBigReward().getRemainingTimes() <= 0){
                return GameErrorCode.E_RECALL_PLAYER_NO_CHANGE_BIG_REWARD_THIS_FLOOR;
            }
            getChosenBigReward().setReward(reward);
        }
        userRecallSelfData.setUpdateOption();

        RecallPlayerProto.UserChooseBigRewardRespMsg.Builder builder = RecallPlayerProto.UserChooseBigRewardRespMsg.newBuilder();
        builder.setRet(0);
        builder.setFloor(userRecallSelfData.getFloor());
        for (RecallPlayerFloorCellData cellData : userRecallSelfData.getCellDataList()) {
            RecallPlayerProto.DrawFloorCellData.Builder cellMsg = RecallPlayerPb.parseDrawFloorCellMsg(cellData);
            builder.addDrawFloorCellData(cellMsg);
        }
        builder.setHasDrawTimeThisFloor(userRecallSelfData.getHasDrawTimeThisFloor());
        builder.setTotalDrawTime(userRecallSelfData.getTotalDrawTime());

        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_CHOOSE_BIG_REWARD, builder);
        return 0;

    }

    /**
     * 获取本层数大奖 没有的话给null
     */
    public RecallPlayerFloorCellData getChosenBigReward() {
        List<RecallPlayerFloorCellData> cellDataList = userRecallSelfData.getCellDataList();
        for (RecallPlayerFloorCellData data : cellDataList) {
            if (data.isSpecial()) {
                return data;
            }
        }
        return null;
    }

    /**
     * 接收系统传来更新任务的数据
     */
    public void updateTaskFromSystem(eRecallPlayerConditionTypeEnum type, BigInteger value) {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return; //活动不存在没必要
        }
        if (beBindData == null || beBindData.getRecallCode().isEmpty()) {
            return;             //召回码空的 没必要
        }
        long now = System.currentTimeMillis();
        List<RecallPlayerBeBindTaskValue> taskInfos = beBindData.getTaskInfos();
        if (taskInfos == null){
            generateTaskValueList();
        }
        for (RecallPlayerBeBindTaskValue taskValue : taskInfos) {
            if (taskValue.getTaskType() == type.getValue()) {
                if (type == eRecallPlayerConditionTypeEnum.totalEarnRise || type == eRecallPlayerConditionTypeEnum.userLevel) {
                    if (value.compareTo(taskValue.getTaskValue()) > 0) {
                        taskValue.setTaskValue(value);
                        taskValue.setNeedUpdate(true);
                        taskValue.setLastUpdateTime(now);
                    }
                    beBindData.setUpdateOption();
                    return;
                }

                if (type == eRecallPlayerConditionTypeEnum.rechargeAfterBind){
                    taskValue.setTaskValue(taskValue.getTaskValue().add(value));
                    taskValue.setLastUpdateTime(now);
                    taskValue.setNeedUpdate(true);
                    beBindData.setUpdateOption();
                    return;
                }

                if (type == eRecallPlayerConditionTypeEnum.activeDuringBack) {
                    if (!DateHelper.isSameDay(now/1000, taskValue.getLastUpdateTime()/1000)) {
                        if (value.intValue() >= RecallPlayerMgr.getConfig().getDayAchieveActive()) {
                            taskValue.setLastUpdateTime(now);
                            taskValue.setTaskValue(taskValue.getTaskValue().add(BigInteger.valueOf(1)));
                            taskValue.setNeedUpdate(true);
                            beBindData.setUpdateOption();
                            return;
                        }
                    }
                    return;
                }
                //几种都不是的情况 先不加
                return;
            }
        }
        //如果是新增的
        RecallPlayerBeBindTaskValue newValue = new RecallPlayerBeBindTaskValue();
        newValue.setTaskType(type.getValue());
        newValue.setNeedUpdate(true);
        if (type == eRecallPlayerConditionTypeEnum.rechargeAfterBind){
            newValue.setBindTimeValue(BigInteger.ZERO);
            newValue.setTaskValue(value);
        }else if (type == eRecallPlayerConditionTypeEnum.activeDuringBack){
            newValue.setBindTimeValue(BigInteger.ZERO);
            if (value.intValue() >= RecallPlayerMgr.getConfig().getDayAchieveActive()) {
                newValue.setTaskValue(newValue.getTaskValue().add(BigInteger.valueOf(1)));
            }else {
                newValue.setTaskValue(BigInteger.ZERO);
            }
        }

        beBindData.getTaskInfos().add(newValue);
        beBindData.setUpdateOption();

    }

    /**
     * 20230316  策划说新活动要检测一下 抽过奖的人盘面不能动 没抽过的人这个盘面不能动
     */

    public void checkNewDrawMap() {
        List<RecallPlayerFloorCellData> cellDataList = userRecallSelfData.getCellDataList();
        if (cellDataList == null || cellDataList.isEmpty()) {
            //只有一层 一层物品只有一个 如果要改抽奖设置成多个 这里一定要改
            userRecallSelfData.setCellDataList(generateRewardList(1));
            return;
        }
        if (checkDrawAny()) {
            return;
        }
        Map<Integer, RecallPlayerDrawConfig> drawConfig = RecallPlayerMgr.getConfig().getDrawConfig();
        RecallPlayerDrawConfig recallPlayerDrawConfig = drawConfig.get(1);
        boolean needReset = false;
        List<RecallPlayerSingleSimpleRewardConfig> simpleRewardConfigs = recallPlayerDrawConfig.getSimpleRewardConfigs();
        if (!checkHasAllReward(simpleRewardConfigs)) {
            needReset = true;
        }

        //如果奖励改变了需要重置
        if (needReset) {
            userRecallSelfData.setCellDataList(generateRewardList(1));
        }

    }

    /**
     * 抽奖       20230309策划说改成单轮 奖励单个
     *
     * @return
     */
    public int userDraw() {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND; //活动不存在
        }

        RecallPlayerConfig config = RecallPlayerMgr.getConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND; //活动不存在
        }
        if (userRecallSelfData == null) {
            return GameErrorCode.E_RECALL_PLAYER_NO_OPEN;
        }
        List<RecallPlayerFloorCellData> cellDataList = userRecallSelfData.getCellDataList();
        if (cellDataList == null || cellDataList.isEmpty()) {
            if (userRecallSelfData.getFloor() == 0) {
                userRecallSelfData.setFloor(1);
            }
            userRecallSelfData.setCellDataList(generateRewardList(1));
            return GameErrorCode.E_RECALL_PLAYER_BIG_REWARD_NO_CHOOSE;
        }
        //还未选择大奖
        RecallPlayerFloorCellData bigReward = getChosenBigReward();
        if (bigReward == null) {
            return GameErrorCode.E_RECALL_PLAYER_BIG_REWARD_NO_CHOOSE;
        }
        //没体力了
        if (userRecallSelfData.getRemainingLotteryTimes() <= 0) {
            return GameErrorCode.E_RECALL_PLAYER_DRAW_TIME_NO_ENOUGH;
        }

        // 抽奖!!!
        Map<Integer, RecallPlayerDrawConfig> drawConfigMap = config.getDrawConfig();
        if (drawConfigMap == null) {
            return GameErrorCode.E_RECALL_PLAYER_DRAW_CONFIG_ERROR; //活动不存在
        }
        //先检测是否全部奖励都抽取了
        boolean allDraw = checkAllDraw();
        if (allDraw) {
            return GameErrorCode.E_RECALL_PLAYER_ALL_DRAW;
        }

        RecallPlayerDrawConfig drawConfig = drawConfigMap.get(userRecallSelfData.getFloor());
        if (drawConfig == null) {
            return GameErrorCode.E_RECALL_PLAYER_DRAW_CONFIG_ERROR; //配置有问题
        }

        Property finalReward = new Property();
        //首先检测是否把普通道具全抽了    是的话直接给大奖
        if (checkSimpleAllDrawed()) {

            bigReward.setRemainingTimes(bigReward.getRemainingTimes() - 1);
            finalReward = PropertyHelper.parseStringToProperty(bigReward.getReward());

        } else {    //正常抽
            List<Integer> weightList = new ArrayList<>();
            weightList.add(drawConfig.getRewardsWeights());
            weightList.add(drawConfig.getSpecialRewardWeights());
            int rewardPool = RandomHelper.getRandomIndexByWeight(weightList, new Random());
            if (bigReward.getRemainingTimes() <= 0) {  //如果大奖已经被抽取
                rewardPool = 0;                         //只能是小奖
            }
            //如果是普通的奖励
            if (rewardPool == 0) {
                List<PropertyWeightItem> list = new ArrayList<>();
                List<RecallPlayerSingleSimpleRewardConfig> simpleRewardConfigs = drawConfig.getSimpleRewardConfigs();
                for (RecallPlayerFloorCellData cellData : userRecallSelfData.getCellDataList()) {
                    //没有次数了
                    if (cellData.getRemainingTimes() == 0) {
                        continue;
                    }
                    //新建一个weightItem
                    PropertyWeightItem propertyWeightItem = new PropertyWeightItem();
                    propertyWeightItem.setProperty(new Property());
                    propertyWeightItem.getProperty().addProperty(PropertyHelper.parseStringToProperty(cellData.getReward()));

                    //遍历一下看看有没有这个奖励
                    for (RecallPlayerSingleSimpleRewardConfig simpleRewardConfig : simpleRewardConfigs) {
                        if (cellData.getReward().equals(simpleRewardConfig.getReward())) {
                            //有的话给权重
                            propertyWeightItem.setWeight(simpleRewardConfig.getOneTimeWeight());
                            break;
                        }
                    }
                    //没拿到配置 给个1 免得抽不到了
                    if (propertyWeightItem.getWeight() == 0) {
                        propertyWeightItem.setWeight(1);
                    }
                    list.add(propertyWeightItem);
                }
                if (list.isEmpty()) {
                    return GameErrorCode.E_RECALL_PLAYER_DRAW_DATA_ERROR;
                }
                finalReward = RandomWeightConfigHelper.getPropertyWeightItem(list);
                RecallPlayerFloorCellData cellDataByReward = getSimpleCellDataByReward(PropertyHelper.parsePropertyToString(finalReward));
                if (cellDataByReward == null) {
                    return GameErrorCode.E_RECALL_PLAYER_DRAW_DATA_ERROR;
                }
                cellDataByReward.setRemainingTimes(cellDataByReward.getRemainingTimes() - 1);
            } else {  //如果是抽到大奖了!
                bigReward.setRemainingTimes(bigReward.getRemainingTimes() - 1);
                finalReward.addProperty(PropertyHelper.parseStringToProperty(bigReward.getReward()));
            }
        }
        //先扣抽奖次数
        userRecallSelfData.setRemainingLotteryTimes(userRecallSelfData.getRemainingLotteryTimes() - 1);
        //加记录次数
        userRecallSelfData.setHasDrawTimeThisFloor(userRecallSelfData.getHasDrawTimeThisFloor() + 1);
        userRecallSelfData.setTotalDrawTime(userRecallSelfData.getTotalDrawTime() + 1);
        //入背包
        player.getModule(CurrencyModule.class).addCurrency(finalReward, eLogMoneyType.RecallPlayer, eLogMoneyType.RecallPlayerDrawReward);
        //先日志
        AutoLogMgr.add(new LogRecallPlayerDraw(activityInfo.getActivityId(), getUserId(), userRecallSelfData.getFloor(), bigReward.getReward(), userRecallSelfData.getHasDrawTimeThisFloor(), PropertyHelper.parsePropertyToString(finalReward), new Date(), (bigReward.getRemainingTimes() == 0)));

        //回包
        RecallPlayerProto.UserDrawRespMsg.Builder builder = RecallPlayerProto.UserDrawRespMsg.newBuilder();
        builder.setRet(0);
        builder.setReward(PropertyHelper.parsePropertyToString(finalReward));
        builder.setNewLevel(userRecallSelfData.getFloor());
        for (RecallPlayerFloorCellData recallPlayerFloorCellData : userRecallSelfData.getCellDataList()) {
            RecallPlayerProto.DrawFloorCellData.Builder cellBuilder = RecallPlayerPb.parseDrawFloorCellMsg(recallPlayerFloorCellData);
            builder.addDrawFloorCellData(cellBuilder);
        }
        builder.setHasDrawTimeThisFloor(userRecallSelfData.getHasDrawTimeThisFloor());
        builder.setTotalDrawTime(userRecallSelfData.getTotalDrawTime());
        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_DRAW, builder);
        return 0;
    }

    /**
     * 自动检测进入下一层
     */
    private boolean checkAllDraw() {
        if (userRecallSelfData == null) {
            return false;
        }

        boolean allDrawed = true;
//        Map<Integer, RecallPlayerDrawConfig> configMap = RecallPlayerMgr.getConfig().getDrawConfig();
        for (RecallPlayerFloorCellData recallPlayerFloorCellData : userRecallSelfData.getCellDataList()) {
            if (recallPlayerFloorCellData.getRemainingTimes() > 0) {
                allDrawed = false;
                break;
            }
        }
        return allDrawed;
    }

    /**
     * 查看是否抽过
     *
     * @return
     */

    private boolean checkDrawAny() {
        if (userRecallSelfData == null) {
            return true;
        }
        for (RecallPlayerFloorCellData recallPlayerFloorCellData : userRecallSelfData.getCellDataList()) {
            if (recallPlayerFloorCellData.getRemainingTimes() == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 查看当前的抽奖列表是不是有这个奖励
     *
     * @return
     */

    private boolean checkHasAllReward(List<RecallPlayerSingleSimpleRewardConfig> configs) {
        if (userRecallSelfData == null) {
            return false;
        }

        ArrayList<RecallPlayerFloorCellData> tmpCellData = new ArrayList<>(userRecallSelfData.getCellDataList());
        for (RecallPlayerSingleSimpleRewardConfig config : configs) {

            boolean hasThisReward = false;
            RecallPlayerFloorCellData needRemoveData = null;

            for (RecallPlayerFloorCellData cellData : tmpCellData) {

                if (cellData.isSpecial()) {
                    continue;
                }
                if (cellData.getReward().equals(config.getReward())) {
                    hasThisReward = true;
                    needRemoveData = cellData;
                }

            }
            if (needRemoveData != null) {
                tmpCellData.remove(needRemoveData);
            }
            if (!hasThisReward) {
                return false;
            }
        }
        return true;
    }


    /**
     * 检测普通道具是否全部抽取
     */
    private boolean checkSimpleAllDrawed() {
        if (userRecallSelfData == null) {
            return false;
        }
        List<RecallPlayerFloorCellData> dataList = userRecallSelfData.getCellDataList();
        for (RecallPlayerFloorCellData recallPlayerFloorCellData : dataList) {
            //大奖不管
            if (recallPlayerFloorCellData.isSpecial()) {
                continue;
            }

            if (recallPlayerFloorCellData.getRemainingTimes() != 0) {
                return false;
            }
        }
        return true;
    }

    private RecallPlayerFloorCellData getSimpleCellDataByReward(String reward) {
        List<RecallPlayerFloorCellData> dataList = userRecallSelfData.getCellDataList();
        for (RecallPlayerFloorCellData recallPlayerFloorCellData : dataList) {
            if (recallPlayerFloorCellData.isSpecial()) {
                continue;
            }
            //大奖不管
            if (recallPlayerFloorCellData.getReward().equals(reward)) {
                if (recallPlayerFloorCellData.getRemainingTimes() <= 0) {
                    continue;
                }
                return recallPlayerFloorCellData;
            }
        }
        return null;
    }

    /**
     * 生成抽奖普通奖励列表
     *
     * @param level
     * @return
     */
    private List<RecallPlayerFloorCellData> generateRewardList(int level) {
        Map<Integer, RecallPlayerDrawConfig> drawConfig = RecallPlayerMgr.getConfig().getDrawConfig();
        if (level > drawConfig.size()) {
            level = drawConfig.size();
        }
        RecallPlayerDrawConfig recallPlayerDrawConfig = drawConfig.get(level);
        List<RecallPlayerSingleSimpleRewardConfig> simpleRewardConfigs = recallPlayerDrawConfig.getSimpleRewardConfigs();
        List<RecallPlayerFloorCellData> rewardList = new ArrayList<>();
        for (RecallPlayerSingleSimpleRewardConfig rewardConfig : simpleRewardConfigs) {
            RecallPlayerFloorCellData cellData = new RecallPlayerFloorCellData();
            cellData.setSpecial(false);
            cellData.setRemainingTimes(1);
            cellData.setReward(rewardConfig.getReward());
            rewardList.add(cellData);
        }

        return rewardList;
    }

    private RecallPlayerFloorCellData generateBigReward(String reward) {
        RecallPlayerFloorCellData recallPlayerFloorCellData = new RecallPlayerFloorCellData();
        recallPlayerFloorCellData.setReward(reward);
        recallPlayerFloorCellData.setRemainingTimes(1);
        recallPlayerFloorCellData.setSpecial(true);
        return recallPlayerFloorCellData;
    }


    public void initSystem() {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        if (checkServerOpenDayEnough() && checkUserTitleEnough()) {
            initUserData(activityInfo.getActivityId());
        }

        syncActivityData();
    }

    /**
     * 初始化被绑定信息
     */
    private void initBindData() {
        beBindData = new UserRecallBeBindData();
        beBindData.setUserId(getUserId());
        beBindData.setUserType(0);        //未分级
        beBindData.setInsertOption();
    }


    /**
     * 生成自身绑定任务数据
     *
     * @return
     */
    private List<RecallPlayerBeBindTaskValue> generateTaskValueList() {
        List<RecallPlayerBeBindTaskValue> taskValueList = new ArrayList<>();
        RecallPlayerBeBindTaskValue titleTaskValue = new RecallPlayerBeBindTaskValue();

        //20230309策划删除
//        //头衔任务
//        titleTaskValue.setBindTimeValue(BigInteger.valueOf(player.getUserInfo().getTitleId()));
//        titleTaskValue.setTaskType(eRecallPlayerConditionTypeEnum.userLevel.getValue());
//        titleTaskValue.setTaskValue(BigInteger.valueOf(player.getUserInfo().getTitleId()));
//        taskValueList.add(titleTaskValue);
//
//        //赚速任务
//        RecallPlayerBeBindTaskValue earnTaskValue = new RecallPlayerBeBindTaskValue();
//        earnTaskValue.setBindTimeValue(player.getUserInfo().getEarnSpeed());
//        earnTaskValue.setTaskType(eRecallPlayerConditionTypeEnum.totalEarnRise.getValue());
//        earnTaskValue.setTaskValue(player.getUserInfo().getEarnSpeed());
//        taskValueList.add(earnTaskValue);

        //绑后充值
        RecallPlayerBeBindTaskValue rechargeTaskValue = new RecallPlayerBeBindTaskValue();
        long recharge = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.TotalRecharge);
        rechargeTaskValue.setBindTimeValue(BigInteger.valueOf(recharge));
        rechargeTaskValue.setTaskType(eRecallPlayerConditionTypeEnum.rechargeAfterBind.getValue());
        rechargeTaskValue.setTaskValue(BigInteger.valueOf(recharge));
        taskValueList.add(rechargeTaskValue);
        //绑后活跃
        RecallPlayerBeBindTaskValue activeTaskValue = new RecallPlayerBeBindTaskValue();
        activeTaskValue.setBindTimeValue(BigInteger.valueOf(0));
        activeTaskValue.setTaskType(eRecallPlayerConditionTypeEnum.activeDuringBack.getValue());
        activeTaskValue.setTaskValue(BigInteger.valueOf(0));
        taskValueList.add(activeTaskValue);

        beBindData.setTaskInfos(taskValueList);
        return taskValueList;

    }

    /**
     * 同步活动绑定与被绑定信息
     */
    public void syncActivityData() {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return;
        }

        if (beBindData != null) {
            syncBindData();
        }

        if (userRecallSelfData != null) {
            syncBindPlayerSelfData();
        }
        Map<Integer, List<UserRecallOtherData>> userBindOtherMap = RecallPlayerMgr.getUserRecallAllOtherData(getUserId());

        syncBindOtherData(userBindOtherMap);
    }

    /**
     * 同步活动被绑定信息
     */

    private void syncBindData() {
        RecallPlayerProto.UserRecallBeBindDataSyncMsg.Builder syncMsg = RecallPlayerProto.UserRecallBeBindDataSyncMsg.newBuilder();
        syncMsg.setActivityId(RecallPlayerMgr.getActivityInfo().getActivityId());
        syncMsg.setRecallCode(beBindData.getRecallCode());
        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_BIND_SYNC, syncMsg);
    }

    /**
     * 同步玩家绑定他人信息
     */
    public void syncBindOtherData(Map<Integer, List<UserRecallOtherData>> userRecallOtherDataMap) {
        if (userRecallOtherDataMap == null) {
            return;
        }
        if (userRecallOtherDataMap.isEmpty()){
            return;
        }
        RecallPlayerProto.UserRecallAllUserDataSyncMsg.Builder builder = RecallPlayerProto.UserRecallAllUserDataSyncMsg.newBuilder();
        synchronized (userRecallOtherDataMap){
            for (Map.Entry<Integer, List<UserRecallOtherData>> entry : userRecallOtherDataMap.entrySet()) {
                RecallPlayerProto.UserRecallOtherTypeList.Builder listBuilder = RecallPlayerProto.UserRecallOtherTypeList.newBuilder();
                listBuilder.setBindUserType(entry.getKey());
                for (UserRecallOtherData userRecallOtherData : entry.getValue()) {
                    RecallPlayerProto.UserRecallOtherData.Builder dataBuilder = RecallPlayerProto.UserRecallOtherData.newBuilder();
                    dataBuilder.setRecallUserServer(userRecallOtherData.getRecallUserServer());
                    dataBuilder.setRecallUserId(userRecallOtherData.getRecallUserId());
                    dataBuilder.setPlayerType(userRecallOtherData.getPlayerType());
                    dataBuilder.setRecallTime(userRecallOtherData.getRecallTime());
                    dataBuilder.setHasNoRewardFinishTask(userRecallOtherData.isHasFinishTask());
                    UserBaseInfo userBaseInfo = recallUserBaseInfoMap.get(userRecallOtherData.getRecallUserId());
                    if (userBaseInfo == null) {
                        log.error("绑定玩家 {} 数据不存在", userRecallOtherData.getRecallUserId());
                    } else {
                        dataBuilder.setRecallUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                    }
                    listBuilder.addRecallOtherData(dataBuilder);
                }
                builder.addUserRecallOtherTypeList(listBuilder);
            }
        }
        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_RECALL_OTHER_DATA_SYNC, builder);

    }

    /**
     * 同步玩家个人数据
     */
    private void syncBindPlayerSelfData() {
        if (userRecallSelfData == null){
            return;
        }
        RecallPlayerProto.UserRecallSelfDataSyncMsg.Builder builder = RecallPlayerProto.UserRecallSelfDataSyncMsg.newBuilder();
        builder.setRecallCode(userRecallSelfData.getRecallCode());
        builder.setHasFirstShared(userRecallSelfData.getHasFirstShared());
        builder.setRemainingLotteryTimes(userRecallSelfData.getRemainingLotteryTimes());
        builder.setFloor(userRecallSelfData.getFloor());
        if (userRecallSelfData.getCellDataList() == null || userRecallSelfData.getCellDataList().isEmpty()) {
            userRecallSelfData.setCellDataList(generateRewardList(userRecallSelfData.getFloor()));
        }
        for (RecallPlayerFloorCellData recallPlayerFloorCellData : userRecallSelfData.getCellDataList()) {
            RecallPlayerProto.DrawFloorCellData.Builder cellBuilder = RecallPlayerPb.parseDrawFloorCellMsg(recallPlayerFloorCellData);
            builder.addDrawFloorCellData(cellBuilder);
        }
        builder.setHasDrawTimeThisFloor(userRecallSelfData.getHasDrawTimeThisFloor());
        builder.setTotalDrawTime(userRecallSelfData.getTotalDrawTime());

        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_SELF_DATA_SYNC, builder);

    }

    /**
     * 用邀请码去拿玩家数据
     */
    public int getNewestUserInfoByRecallCode(String recallCode) {
        List<Long> userInfoByRecallCode = getUserInfoByRecallCode(recallCode);
        if (userInfoByRecallCode == null) {
            return GameErrorCode.E_RECALL_PLAYER_CODE_ERROR;  //召回码有误
        }
        long serverId = userInfoByRecallCode.get(0);
        long playerId = userInfoByRecallCode.get(1);
        ServerInfo serverInfo = ServerListMgr.getServerInfo(serverId);
        if (serverInfo == null || !serverInfo.isOpen()) {
            return GameErrorCode.E_RECALL_PLAYER_CODE_ERROR;  //召回码有误
        }
        if (GameServer.getInstance().getServerId() == serverId) {
            RecallPlayerProto.GetPlayerByRecallCodeRespMsg.Builder builder = RecallPlayerProto.GetPlayerByRecallCodeRespMsg.newBuilder();
            UserBaseInfo userInfo = UserMgr.getUserBaseInfo(playerId, serverId);
            if (userInfo == null) {
                return GameErrorCode.E_RECALL_PLAYER_CODE_ERROR;  //召回码有误
            }
            builder.setRet(0);
            builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userInfo));
            player.sendPacket(ClientProtocol.U_CHECK_RECALL_PLAYER_CODE_CORRECT, builder);
            return 0;
        } else {
            RecallPlayerProto.RecallPlayerCrossGetUserInfoReq.Builder builder = RecallPlayerProto.RecallPlayerCrossGetUserInfoReq.newBuilder();
            builder.setRecallUserServer(userInfoByRecallCode.get(0));
            builder.setRecallUserId(userInfoByRecallCode.get(1));
            builder.setOperation(2);
            player.sendPacket(CrossProtocol.C_PLAYER_RECALL_UPDATE_RETURN_USER_INFO, builder);
            return 0;
        }
    }

    /**
     * 跨服返回玩家用邀请码获取的数据
     */
    public void returnUserGetInfoByCode(int ret, UserBaseInfo userBaseInfo) {
        RecallPlayerProto.GetPlayerByRecallCodeRespMsg.Builder builder = RecallPlayerProto.GetPlayerByRecallCodeRespMsg.newBuilder();
        builder.setRet(ret);
        if (userBaseInfo != null) {
            builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        }
        player.sendPacket(ClientProtocol.U_CHECK_RECALL_PLAYER_CODE_CORRECT, builder);
    }


    /**
     * 填写召回码
     *
     * @param recallCode 召回码
     * @return ret
     */
    public int writeRecallCode(String recallCode) {

        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND; //活动不存在
        }
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(player.getUserId());
        if (userData == null) {
            return GameErrorCode.E_PLAYER_RETURN_NOT_RETURN_ROLE; //不是回归玩家
        }
        int ret = player.getModule(OldPlayerReturnModule.class).checkReturnRoleIsEffective(userData);
        if (ret != 0) {
            return GameErrorCode.E_PLAYER_RETURN_NOT_RETURN_ROLE; //不是回归玩家
        }
        List<Long> userInfoIdList = getUserInfoByRecallCode(recallCode);
        if (userInfoIdList == null) {
            return GameErrorCode.E_RECALL_PLAYER_CODE_ERROR;  //召回码有误
        }
        long serverId = userInfoIdList.get(0);

        long playerId = userInfoIdList.get(1);
        ServerInfo serverInfo = ServerListMgr.getServerInfo(serverId);
        if (serverInfo == null || !serverInfo.isOpen()) {
            return GameErrorCode.E_RECALL_PLAYER_CODE_ERROR;  //召回码有误
        }
        if (playerId == player.getUserId()) {
            if (userRecallSelfData == null || !Objects.equals(recallCode, userRecallSelfData.getRecallCode())) {
                return GameErrorCode.E_RECALL_PLAYER_CODE_ERROR; //召回码有误
            }
            return GameErrorCode.E_RECALL_PLAYER_WRITE_SELF_CODE; //不能填写自己的召回码
        }
        if (beBindData != null && beBindData.isBind()) {
            return GameErrorCode.E_RECALL_PLAYER_ALREADY_BIND; //已经填写过
        }
        if (beBindData == null) {
            initBindData();
        }

        int type = RecallPlayerMgr.calculateReturnPlayerType(player.getUserInfo().getEarnSpeed());
        if (type == 0) {
            return GameErrorCode.E_RECALL_PLAYER_EARN_SPEED_NO_ENOUGH;
        }
        generateTaskValueList();    //每次填写的时候重新生成任务
        if (serverId == GameServer.getInstance().getServerId()) {
            PlayerProto.PlayerBaseTempMsg.Builder playerBaseTempMsg = PlayerPb.parsePlayerBaseTempMsg(player.getUserInfo());
            UserBaseInfo userBaseInfo = PlayerBasePb.parseBaseUserInfo(playerBaseTempMsg.build());
            ret = RecallPlayerMgr.recallBind(playerId, player.getUserId(), userBaseInfo, recallCode, type, beBindData.getTaskInfos());
            if (ret == 0) {
                recallBindSuccess(recallCode);
            }
            return ret;
        }
        beBindData.setPreBindRecallCode(recallCode);

        RecallPlayerProto.WriteRecallCodeServerReqCrossMsg.Builder reqCrossBuilder = RecallPlayerProto.WriteRecallCodeServerReqCrossMsg.newBuilder();
        reqCrossBuilder.setRecallCode(recallCode);
        reqCrossBuilder.setReqBindServerId(serverId);
        reqCrossBuilder.setReqBindUserId(playerId);
        reqCrossBuilder.setRecallUserInfo(PlayerPb.parsePlayerBaseTempMsg(player.getUserInfo()));
        reqCrossBuilder.setReqBindUserType(type);

        for (RecallPlayerBeBindTaskValue value : beBindData.getTaskInfos()) {
            RecallPlayerProto.BindTaskInfo.Builder taskBuilder = RecallPlayerPb.parseBindTaskValueMsg(value);
            reqCrossBuilder.addTaskInfo(taskBuilder);
        }


        player.sendPacket(CrossProtocol.C_RECALL_PLAYER_BIND, reqCrossBuilder);
        return 0;

    }

    /**
     * 根据召回码解析出 serverId(index:0) userId(index:1)
     *
     * @param recallCode 召回码
     * @return list 解析有问题 返回null
     */
    public List<Long> getUserInfoByRecallCode(String recallCode) {
        List<Long> list = new ArrayList<>();
        if (!RecallPlayerMgr.checkStringAllInDigits(recallCode)) {
            return null;
        }
        long userId = RecallPlayerMgr.sixtyTwoToTenHex(recallCode);
        String userIdStr = String.valueOf(userId);
        if (userIdStr.length() != 15) {
            return null;
        }
        long serverId = Long.parseLong(userIdStr.substring(0, 8));
        list.add(0, serverId);
        list.add(1, userId);
        return list;
    }

    /**
     * 召回绑定成功
     *
     * @param recallCode 召回码
     */
    public void recallBindSuccess(String recallCode) {
        if (beBindData == null) {
            return;
        }
        if (!beBindData.getRecallCode().isEmpty()) {
            return;
        }
        //跟预存的召回码不一致
        if (!beBindData.getPreBindRecallCode().isEmpty() && !Objects.equals(recallCode, beBindData.getPreBindRecallCode())) {
            log.error("recallPlayerModule bind recallCode and preRecallCode diff, recallCode:{}, preRecallCode:{}, playerId:{}",
                    recallCode, beBindData.getRecallCode(), player.getUserId());
        }
        //Property reward = RandomWeightConfigHelper.getPoolWeightDrawResult(RecallPlayerMgr.getConfig().getWriteCodeReward());
        beBindData.recallBindSuccess(recallCode);
        String rewardString = RecallPlayerMgr.getConfig().getWriteCodeReward();
        Property reward = PropertyHelper.parseStringToProperty(rewardString);
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.RecallPlayer, eLogMoneyType.RecallPlayerBindReward);

        RecallPlayerProto.RecallPlayerWriteRecallCodeRespMsg.Builder respMsg = RecallPlayerProto.RecallPlayerWriteRecallCodeRespMsg.newBuilder();
        respMsg.setReward(rewardString);
        respMsg.setRet(0);

        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_WRITE_RECALL_CODE, respMsg);

        syncBindData();
        long bindPlayerId = 0;
        List<Long> userInfoIdList = getUserInfoByRecallCode(beBindData.getRecallCode());
        if (userInfoIdList != null) {
            bindPlayerId = userInfoIdList.get(1);
        }
        AutoLogMgr.add(new LogRecallUser(beBindData.getUserId(), beBindData.getRecallCode(), bindPlayerId, PropertyHelper.parsePropertyToString(reward), new Date()));
    }

    /**
     * 被绑定后玩家上线初始化数据
     */
    public void newBindPlayerInit(Map<Integer, List<UserRecallOtherData>> userRecallAllOtherDataMap) {
        synchronized (userRecallAllOtherDataMap){
            for (Map.Entry<Integer, List<UserRecallOtherData>> entry : userRecallAllOtherDataMap.entrySet()) {
                player.notifyListener(eGamePlayerEventType.ActivePlayerRecallOldPlayerNum.getValue(), new RecallPlayerActivitySumArgs(entry.getKey(), entry.getValue().size()));
                //      player.notifyListener(); 个人邀请成就
                for (UserRecallOtherData userRecallOtherData : entry.getValue()) {
                    if (!userRecallOtherData.isHadInit()) {
                        userRecallOtherData.setHadInit(true);
                        generateTaskList(userRecallOtherData.getRecallUserId(), userRecallOtherData.getPlayerType(), userRecallOtherData.getTaskData());
                        RecallPlayerTypeConfig recallTypeConfig = RecallPlayerMgr.getRecallTypeConfig(userRecallOtherData.getPlayerType());
                        if (recallTypeConfig != null) {
                            userRecallSelfData.setRemainingLotteryTimes(userRecallSelfData.getRemainingLotteryTimes() + recallTypeConfig.getDrawNum());   //加抽奖次数
                        } else {
                            userRecallSelfData.setRemainingLotteryTimes(userRecallSelfData.getRemainingLotteryTimes() + 1);   //加抽奖次数
                        }
                    }
                }
            }
        }

    }

    /**
     * 更新所有绑定玩家任务
     */

    public void updateAllBindUserTask(Map<Integer, List<UserRecallOtherData>> userRecallAllOtherDataMap) {
        synchronized (userRecallAllOtherDataMap){
            for (List<UserRecallOtherData> userRecallOtherDataList : userRecallAllOtherDataMap.values()) {
                for (UserRecallOtherData userRecallOtherData : userRecallOtherDataList) {
                    updateTaskList(userRecallOtherData.getRecallUserId(), userRecallOtherData.getPlayerType(), userRecallOtherData.getTaskData());
                }
            }
        }
    }


    /**
     * 更新任务数据
     */
    public void updateTaskList(long returnPlayerId, int returnPlayType, List<RecallPlayerBeBindTaskValue> taskValueList) {
        UserRecallOtherData userRecallOtherData = RecallPlayerMgr.getUserRecallOtherData(getUserId(), returnPlayerId);
        if (userRecallOtherData == null) {
            log.error("玩家{}收到了来自玩家{}的任务数据,但绑定数据未找到该玩家", getUserId(), returnPlayerId);
            return;
        }
        if (taskValueList == null || taskValueList.isEmpty()) {
            return;
        }
        if (bindingUserTaskDataMap.get(returnPlayerId) == null) {
            synchronized (bindingUserTaskDataMap) {
                if (bindingUserTaskDataMap.get(returnPlayerId) == null) {
                    generateTaskList(returnPlayerId, returnPlayType, taskValueList);
                }
            }
        }


        List<RecallPlayerBindingTaskData> taskDataList = bindingUserTaskDataMap.get(returnPlayerId);
        if (taskDataList == null) {
            log.error("活动id为{}的汴梁达人活动玩家{}生成绑定任务失败", RecallPlayerMgr.getActivityInfo().getActivityId(), getUserId());
            return;
        }
        for (RecallPlayerBeBindTaskValue taskValue : taskValueList) {
            if (!taskValue.isNeedUpdate()) {
                continue;
            }
            for (RecallPlayerBindingTaskData taskData : taskDataList) {
                if (taskData.getTaskType() == taskValue.getTaskType()) {
                    taskData.setOldValue(taskValue.getBindTimeValue());
                    taskData.setNowValue(taskValue.getTaskValue());
                    taskData.setModifyTime(System.currentTimeMillis());
                }
            }
            //置位false防止重复更新
            taskValue.setNeedUpdate(false);
        }
        //红点
        checkRedDot(returnPlayerId, taskDataList);
    }

    /**
     * 红点检测
     */
    private void checkRedDot(long returnPlayerId, List<RecallPlayerBindingTaskData> bindingTaskDataList) {
        UserRecallOtherData userRecallOtherData = RecallPlayerMgr.getUserRecallOtherData(getUserId(), returnPlayerId);
        for (RecallPlayerBindingTaskData bindingTaskData : bindingTaskDataList) {
            ActivityConditionInfo conditionById = RecallPlayerMgr.getConditionById(bindingTaskData.getTaskId());
            boolean canFinish = checkConditionCanFinish(bindingTaskData, conditionById);
            if (canFinish) {
                userRecallOtherData.setHasFinishTask(true);
                return;
            }
        }
        userRecallOtherData.setHasFinishTask(false);
    }


    /**
     * 生成绑定任务列表
     */
    private void generateTaskList(long returnPlayerId, int returnPlayType, List<RecallPlayerBeBindTaskValue> taskValueList) {
        if (bindingUserTaskDataMap.containsKey(returnPlayerId)) {
            return;
        }
        List<RecallPlayerBindingTaskData> taskDataList = new ArrayList<>();
        List<ActivityConditionInfo> recallPlayerTaskConfigList = RecallPlayerMgr.getAllTaskList();
        for (ActivityConditionInfo recallPlayerTaskConfig : recallPlayerTaskConfigList) {
            if (recallPlayerTaskConfig.getParamList().get(0).intValue() == returnPlayType) {
                RecallPlayerBindingTaskData recallPlayerBindingTaskData = new RecallPlayerBindingTaskData();
                recallPlayerBindingTaskData.setUserId(getUserId());
                recallPlayerBindingTaskData.setBindUserId(returnPlayerId);
                recallPlayerBindingTaskData.setTaskId(recallPlayerTaskConfig.getConditionId());
                recallPlayerBindingTaskData.setTaskType(recallPlayerTaskConfig.getType());
                recallPlayerBindingTaskData.setOldValue(BigInteger.ZERO);
                recallPlayerBindingTaskData.setNowValue(BigInteger.ZERO);
                recallPlayerBindingTaskData.setInsertOption();
                for (RecallPlayerBeBindTaskValue taskValue : taskValueList) {
                    if (taskValue.getTaskType() == recallPlayerBindingTaskData.getTaskType()) {
                        recallPlayerBindingTaskData.setOldValue(taskValue.getBindTimeValue());
                        recallPlayerBindingTaskData.setNowValue(taskValue.getTaskValue());
                        break;
                    }
                }
                recallPlayerBindingTaskData.setGotRewarded(false);
                recallPlayerBindingTaskData.setModifyTime(System.currentTimeMillis());
                taskDataList.add(recallPlayerBindingTaskData);
            }
        }
        bindingUserTaskDataMap.put(returnPlayerId, taskDataList);


    }

    /**
     * 恢复预召回状态
     */
    public void resetPreBind() {
        if (beBindData == null) {
            return;
        }
        beBindData.resetPreBind();
    }

    /**
     * 分享成功领奖
     */
    public void shareSuccess() {
        RecallPlayerProto.PlayerRecallShareCodeSuccessRespMsg.Builder builder = RecallPlayerProto.PlayerRecallShareCodeSuccessRespMsg.newBuilder();
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();

        if (activityInfo == null) {
            builder.setRet(GameErrorCode.E_RECALL_PLAYER_NO_OPEN);
            player.sendPacket(ClientProtocol.U_RECALL_PLAYER_SHARE_SUCCESS, builder);
            return;
        }

        if (userRecallSelfData == null) {
            builder.setRet(GameErrorCode.E_RECALL_PLAYER_SYSTEM_NO_OPEN);
            player.sendPacket(ClientProtocol.U_RECALL_PLAYER_SHARE_SUCCESS, builder);
            return;
        }
        if (userRecallSelfData.getHasFirstShared()) {
            builder.setRet(GameErrorCode.E_RECALL_PLAYER_HAS_SHARED);
            player.sendPacket(ClientProtocol.U_RECALL_PLAYER_SHARE_SUCCESS, builder);
            return;
        }
        userRecallSelfData.setHasFirstShared(true);
        String rewardString = GameConfig.GAME_MONEY_INGOTS + "=" + RecallPlayerMgr.getConfig().getShareIngots();

        player.getModule(CurrencyModule.class).addCurrency(rewardString, eLogMoneyType.RecallPlayer, eLogMoneyType.RecallPlayerShare);
        builder.setRet(0);
        builder.setReward(rewardString);
        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_SHARE_SUCCESS, builder);
    }

    /**
     * 绑定玩家数据与任务发回活跃玩家
     *
     * @param bindUserId
     * @param userBaseInfo
     */

    public void sendUserInfoAndTaskData(long bindUserId, UserBaseInfo userBaseInfo) {
        RecallPlayerProto.TaskInfoAndUserBaseInfoRespMsg.Builder builder = RecallPlayerProto.TaskInfoAndUserBaseInfoRespMsg.newBuilder();


        if (userBaseInfo == null) {
            log.error("玩家id{} 的 UserBaseInfo 在玩家所在服务器上未找到", bindUserId);
            userBaseInfo = recallUserBaseInfoMap.get(bindUserId);
            if (userBaseInfo == null) {
                log.error("玩家id{} 的 UserBaseInfo 本地服务器上未缓存", bindUserId);
                builder.setRet(GameErrorCode.E_RECALL_PLAYER_NO_FIND_USER);
                player.sendPacket(ClientProtocol.U_RECALL_PLAYER_TASK_INFO_DETAIL, builder);
                return;
            }
        } else {
            //更新一下数据先
            recallUserBaseInfoMap.put(bindUserId, userBaseInfo);
            //更新数据库
            RecallPlayerBusiness.updateBindUserInfo(userBaseInfo, getUserId(), bindUserId);
        }

        //取任务
        List<RecallPlayerBindingTaskData> taskDataList = bindingUserTaskDataMap.get(bindUserId);
        if (taskDataList == null) {  //任务数据不存在!!!
            builder.setRet(GameErrorCode.E_RECALL_PLAYER_BIND_TASK_DATA_ERROR);
            player.sendPacket(ClientProtocol.U_RECALL_PLAYER_TASK_INFO_DETAIL, builder);
            return;
        }
        //绑定玩家的信息
        builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        //任务
        for (RecallPlayerBindingTaskData bindingTaskData : taskDataList) {
            RecallPlayerProto.BindingTaskData.Builder taskBuilder = RecallPlayerPb.parseBindTaskMsg(bindingTaskData);
            builder.addTaskData(taskBuilder);
        }
        builder.setRet(0);
        player.sendPacket(ClientProtocol.U_RECALL_PLAYER_TASK_INFO_DETAIL, builder);
    }

    /**
     * 更新本地存的用户信息与
     *
     * @return
     */

    public int updateAndGetBindReturnUserInfo(long bindUserServerId, long bindUserId) {

        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_RECALL_PLAYER_NO_OPEN;
        }

        UserRecallOtherData userRecallOtherData = RecallPlayerMgr.getUserRecallOtherData(getUserId(), bindUserId);

        if (userRecallOtherData == null) {       //如果没绑定过这个人
            return GameErrorCode.E_RECALL_PLAYER_NO_BIND_THIS_PLAYER;
        }
        long thisServerId = GameServer.getInstance().getServerId();
        //如果绑定的回归玩家玩家也是本服的
        if (bindUserServerId == thisServerId) {
            UserBaseInfo userInfo = UserMgr.getUserBaseInfo(bindUserId, thisServerId);
            sendUserInfoAndTaskData(bindUserId, userInfo);
        } else {        //绑定的回归玩家不是发送到跨服请求一下最新玩家数据
            RecallPlayerProto.RecallPlayerCrossGetUserInfoReq.Builder builder = RecallPlayerProto.RecallPlayerCrossGetUserInfoReq.newBuilder();
            builder.setRecallUserServer(bindUserServerId);
            builder.setRecallUserId(bindUserId);
            builder.setOperation(1);
            player.sendPacket(CrossProtocol.C_PLAYER_RECALL_UPDATE_RETURN_USER_INFO, builder);
        }
        return 0;
    }

    /**
     * 加载来自数据库中绑定玩家的用户数据
     */
    private void loadBindUserInfoCache() {
        recallUserBaseInfoMap = RecallPlayerBusiness.getBindUserBaseInfoMap(getUserId());
    }

    /**
     * 同步自身绑定任务给活跃玩家
     */

    public void syncBindPlayerTaskData() {
        if (RecallPlayerMgr.getActivityInfo() == null) {
            return;
        }
        if (beBindData == null) {
            return;
        }
        if (beBindData.getRecallCode() == null || beBindData.getRecallCode().isEmpty()) {
            return;
        }
        if (beBindData.getTaskInfos() == null) {
            return;
        }

        //判断是不是本服的
        List<Long> userInfoByRecallCode = getUserInfoByRecallCode(beBindData.getRecallCode());
        if (userInfoByRecallCode == null) {
            return;
        }
        if (GameServer.getInstance().getServerId() == userInfoByRecallCode.get(0)) {
            RecallPlayerMgr.UpdateBindTask(getUserId(), userInfoByRecallCode.get(1), beBindData.getTaskInfos());
            return;
        }

        boolean needSend = false;
        RecallPlayerProto.SyncBindTaskDataMsg.Builder builder = RecallPlayerProto.SyncBindTaskDataMsg.newBuilder();
        for (RecallPlayerBeBindTaskValue taskValue : beBindData.getTaskInfos()) {
            if (taskValue.isNeedUpdate()) {
                needSend = true;
                builder.addTaskInfo(RecallPlayerPb.parseBindTaskValueMsg(taskValue));
            }
        }
        if (needSend) {

            builder.setRecallUserId(getUserId());
            builder.setSyncToServerId(userInfoByRecallCode.get(0));
            builder.setSyncToUserId(userInfoByRecallCode.get(1));
            player.sendPacket(CrossProtocol.C_PLAYER_RECALL_BIND_TASK_SYNC, builder);
        }
    }

    public Map<Long, UserBaseInfo> getRecallUserBaseInfoMap() {
        return recallUserBaseInfoMap;
    }

    public void setRecallUserBaseInfoMap(Map<Long, UserBaseInfo> recallUserBaseInfoMap) {
        this.recallUserBaseInfoMap = recallUserBaseInfoMap;
    }

    //完成任务
    public int finishBindTask(int taskId, long bindUserId) {
        ActivityInfo activityInfo = RecallPlayerMgr.getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_RECALL_PLAYER_NO_OPEN;
        }
        if (RecallPlayerMgr.getConfig() == null) {
            return GameErrorCode.E_RECALL_PLAYER_NO_OPEN;
        }
        if (bindingUserTaskDataMap.get(bindUserId) == null) {
            return GameErrorCode.E_RECALL_PLAYER_BIND_TASK_DATA_ERROR;
        }
        //去取任务配置
        ActivityConditionInfo conditionById = RecallPlayerMgr.getConditionById(taskId);
        if (conditionById == null) {
            return GameErrorCode.E_RECALL_PLAYER_DRAW_CONFIG_ERROR;
        }
        //任务列表中找出任务
        List<RecallPlayerBindingTaskData> bindingTaskDataList = bindingUserTaskDataMap.get(bindUserId);
        for (RecallPlayerBindingTaskData taskData : bindingTaskDataList) {
            if (taskData.getTaskId() == taskId) {
                if (taskData.getGotRewarded()) {
                    return GameErrorCode.E_RECALL_PLAYER_TASK_HAS_GOT_REWARD;
                }
                boolean finish = checkConditionCanFinish(taskData, conditionById);
                if (finish) {
                    taskData.setGotRewarded(true);      //先设置已领奖
                    Property reward = conditionById.getReward();
                    player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.RecallPlayer, eLogMoneyType.RecallPlayerFinishBindTask);
                    RecallPlayerProto.UserFinishTaskRespMsg.Builder builder = RecallPlayerProto.UserFinishTaskRespMsg.newBuilder();
                    builder.setRet(0);
                    builder.setReward(PropertyHelper.parsePropertyToString(reward));
                    player.sendPacket(ClientProtocol.U_RECALL_PLAYER_BIND_TASK_FINISH, builder);
                    AutoLogMgr.add(new LogRecallPlayerFinishBindUserTaskReward(activityInfo.getActivityId(), getUserId(), bindUserId, taskId, PropertyHelper.parsePropertyToString(reward), new Date()));
                    checkRedDot(bindUserId, bindingTaskDataList);

                    return 0;
                } else {
                    return GameErrorCode.E_RECALL_PLAYER_TASK_NO_FINISH;
                }
            }
        }
        return 0;
    }

    private boolean checkConditionCanFinish(RecallPlayerBindingTaskData taskData, ActivityConditionInfo conditionById) {
        if (taskData.getGotRewarded()) {     //已经领奖过
            return false;
        }
//        if (taskData.getTaskType() == eRecallPlayerConditionTypeEnum.userLevel.getValue()) {
//            return taskData.getNowValue().compareTo(conditionById.getParamList().get(3)) >= 0;
//        }
//        if (taskData.getTaskType() == eRecallPlayerConditionTypeEnum.totalEarnRise.getValue()) {
//            return taskData.getNowValue().subtract(taskData.getOldValue()).compareTo(conditionById.getParamList().get(3)) >= 0;
//        }
        if (taskData.getTaskType() == eRecallPlayerConditionTypeEnum.rechargeAfterBind.getValue()) {
            return taskData.getNowValue().subtract(taskData.getOldValue()).compareTo(conditionById.getParamList().get(3)) >= 0;
        }
        if (taskData.getTaskType() == eRecallPlayerConditionTypeEnum.activeDuringBack.getValue()) {
            return taskData.getNowValue().compareTo(conditionById.getParamList().get(2)) >= 0;
        }
        return false;
    }


}


